﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Microsoft.Data.ConnectionUI;
using WeifenLuo.WinFormsUI.Docking;
using MyToolkit.Com;
using Bing.Toolkit.Data.SQL;
using Bing.Toolkit.Data;

namespace MyToolkit
{

    public delegate void ClickMenuHandler(object sender, DatabaseExplorerEventArgs e);

    public partial class FrmDatabaseExplorer : DockContent
    {
        public event ClickMenuHandler OnClickMenuEvent;

        private Dictionary<string, List<DbTable>> _dict = new Dictionary<string, List<DbTable>>();

        public FrmDatabaseExplorer()
        {
            InitializeComponent();
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            var dialog = new DataConnectionDialog();

            dialog.DataSources.Add(DataSource.SqlDataSource);
            //dialog.DataSources.Add(DataSource.OdbcDataSource);
            dialog.SelectedDataSource = DataSource.SqlDataSource;  
            dialog.SelectedDataProvider = DataProvider.SqlDataProvider;

            if (DataConnectionDialog.Show(dialog) == System.Windows.Forms.DialogResult.OK)
            {
                var strConnectionString = dialog.ConnectionString;
                var strProviderName = dialog.SelectedDataProvider.Name;
                var databaseInfo = GetDatabaseInfomation(strConnectionString);
                var strServerName = databaseInfo["Data Source"].ToString();
                var strDatabaseName = databaseInfo["Initial Catalog"].ToString();
                var entity = Com.DatabaseConnection.Create();

                entity.ServerName = strServerName;
                entity.DataBaseName = strDatabaseName;
                entity.ProviderName = strProviderName;
                entity.ConnectionString = strConnectionString;
                entity.Save();

                var treeNode = new TreeNode(strServerName + "->" + strDatabaseName);
                treeNode.Tag = entity;
                treeView1.Nodes.Add(treeNode);

            }
        }

        private KeyValueObject GetDatabaseInfomation(string strConnectionString)
        {
            var kvObject = new KeyValueObject();
            var arr = strConnectionString.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            if (arr.Length > 0)
            {
                foreach (var entry in arr)
                {
                    var tmp = entry.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
                    kvObject.AddKeyValue(tmp[0], tmp[1]);
                }
            }
            return kvObject;
        }

        private void FrmDatabaseExplorer_Load(object sender, EventArgs e)
        {
            LoadDatabase();
        }

        private void LoadDatabase()
        {
            treeView1.Nodes.Clear();

            var lstDbConnection = DatabaseConnection.GetAll();

            for (var i = 0; i < lstDbConnection.Count; i++)
            {
                AddNodeWithDatabaseConnection(treeView1.Nodes, lstDbConnection[i]);
            }
        }

        private TreeNode CreateNode(string strDisplayText, string nodeName, int imageIndex, int selectImageIndex)
        {
            var node = new TreeNode(strDisplayText);
            node.Name = nodeName;
            node.ImageIndex = imageIndex;
            node.SelectedImageIndex = selectImageIndex;

            return node;
        }

        private void AddNodeWithDatabaseConnection(TreeNodeCollection parent, DatabaseConnection dc)
        {
            TreeNode node = new TreeNode(dc.ServerName + "->" + dc.DataBaseName);
            node.Tag = dc;
            parent.Add(node);
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            if (treeView1.SelectedNode.Level == 0 && treeView1.SelectedNode.Nodes.Count == 0)
            {
                FillDatabaseTreeNode(treeView1.SelectedNode.Tag as DatabaseConnection);
                treeView1.SelectedNode.Expand();
            }
        }

        private void FillDatabaseTreeNode(DatabaseConnection dc)
        {
            try
            {
                using (var db = new SQLServerDAO(dc.ConnectionString))
                {
                    var tsn = CreateNode("表", "tables", 3, 3);
                    var vsn = CreateNode("试图", "views", 3, 3);
                    var spsn = CreateNode("存储过程", "sps", 3, 3);

                    var strSQLScriptTables = "SELECT * FROM sys.tables";
                    var dataTables = db.Query(strSQLScriptTables);
                    foreach (var item in dataTables)
                    {
                        var tmp = CreateNode(item.AsValue<string>("name"), item.AsValue<string>("objectid"), 2, 2);
                        tmp.ContextMenuStrip = contextMenuStrip2;
                        tmp.Tag = dc;
                        tsn.Nodes.Add(tmp);
                    }

                    var strSQLScriptViews = "SELECT * FROM sys.views";
                    var dataVies = db.Query(strSQLScriptViews);
                    foreach (var item in dataVies)
                    {
                        var tmp = CreateNode(item.AsValue<string>("name"), item.AsValue<string>("objectid"), 2, 2);
                        tmp.Tag = dc;
                        vsn.Nodes.Add(tmp);
                    }

                    var strSQLScriptProcedures = "SELECT * FROM sys.objects WHERE type= 'p'";
                    var dataProcedures = db.Query(strSQLScriptProcedures);
                    foreach (var item in dataProcedures)
                    {
                        var tmp = CreateNode(item.AsValue<string>("name"), item.AsValue<string>("objectid"), 2, 2);
                        tmp.Tag = dc;
                        spsn.Nodes.Add(tmp);
                    }
                    treeView1.SelectedNode.Nodes.Add(tsn);
                    treeView1.SelectedNode.Nodes.Add(vsn);
                    treeView1.SelectedNode.Nodes.Add(spsn);
                }
            }
            catch
            {
                treeView1.SelectedNode.ImageIndex = 1;
                treeView1.SelectedNode.SelectedImageIndex = 1;
            }
        }

       
        private void tsmiCodeBuilder_Click(object sender, EventArgs e)
        {
            if (OnClickMenuEvent != null)
            {
                OnClickMenuEvent(this, new DatabaseExplorerEventArgs(this.treeView1.SelectedNode.Tag as DatabaseConnection, 1, this.treeView1.SelectedNode.Text));
            }
        }

        private void treeView1_Click(object sender, EventArgs e)
        {
            this.toolStripButton2.Enabled = treeView1.SelectedNode.Level == 0;
        }

        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            TreeNode node = treeView1.GetNodeAt(e.X, e.Y);
            if (node != null)
            {
                treeView1.SelectedNode = node;
            }
        } 
    }

    public class DatabaseExplorerEventArgs : EventArgs
    {
        public DatabaseConnection Connection { get; private set; }
        /// <summary>
        /// EntityBuilder = 1,DataQuery = 2,InserScript = 3
        /// </summary>
        public int MenuID { get; private set; }

        public string ObjectText { get; private set; }

        public DatabaseExplorerEventArgs(DatabaseConnection dc, int id, string obText)
        {
            Connection = dc;
            MenuID = id;
            ObjectText = obText;
        }
    }
}
